package cn.com.surker.sale.service.impl;

import cn.com.surker.enums.sale.BillTimeTypeEnum;
import cn.com.surker.enums.sale.ContractSubsidyTypeEnum;
import cn.com.surker.enums.system.DayPriceTypeEnum;
import cn.com.surker.enums.sale.SubsidyCountTypeEnum;
import cn.com.surker.enums.system.CheckEnum;
import cn.com.surker.enums.system.IsAutoEnum;
import cn.com.surker.sale.dao.ContractDayPriceDao;
import cn.com.surker.sale.dao.SaleClientDao;
import cn.com.surker.sale.dao.SaleContractDao;
import cn.com.surker.sale.dao.SaleContractSubsidyPriceDao;
import cn.com.surker.sale.entity.ContractDayPrice;
import cn.com.surker.sale.entity.SaleClient;
import cn.com.surker.sale.entity.SaleContract;
import cn.com.surker.sale.entity.SaleContractSubsidyPrice;
import cn.com.surker.sale.service.SaleContractSubsidyPriceBaseService;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.dao.DataSourceInfoDao;
import cn.com.surker.system.dao.SysOriginDao;
import cn.com.surker.system.entity.DataSourceInfo;
import cn.com.surker.system.entity.SysUser;
import cn.com.surker.util.StringUtils;
import cn.com.surker.vo.sale.SaleContractSubsidyPriceVO;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.snaker.engine.SnakerException;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 销售合同补贴费用表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2024-07-26
 */
public abstract class SaleContractSubsidyPriceBaseServiceImpl extends ServiceImpl<SaleContractSubsidyPriceDao, SaleContractSubsidyPrice> implements SaleContractSubsidyPriceBaseService {

    @Resource
    protected SaleContractSubsidyPriceDao mapper;
    @Resource
    protected DataSourceInfoDao dataSourceInfoDao;
    @Resource
    protected SaleContractDao saleContractDao;
    @Resource
    protected SysOriginDao originDao;
    @Resource
    protected SaleClientDao saleClientDao;
    @Resource
    protected ContractDayPriceDao contractDayPriceDao;

    /**
     * 根据条件查询所有的数据
     *
     * @param dto
     * @return
     */
    public RestResultDto findAll(SaleContractSubsidyPrice dto) {

        QueryWrapper<SaleContractSubsidyPrice> query = new QueryWrapper();
        query.setEntity(dto);
        List<SaleContractSubsidyPrice> list = mapper.selectList(query);

        return RestResultDto.success(list);
    }

    /**
     * 分页查询条件
     *
     * @param searchVal 关键字查询
     * @param orgId     公司ID查询
     * @param status    状态
     * @param offset    分页参数,第几页
     * @param limit     分页参数,每页数量
     * @return
     */
    public IPage<SaleContractSubsidyPriceVO> queryPage(String searchVal, Integer orgId, Integer status, String startDate, String endDate, Long pumpNormId, String sales, Integer offset, Integer limit) {
        PageHelper.offsetPage(offset, limit);
        Page<SaleContractSubsidyPriceVO> voPage = new Page<>((offset + limit) / limit, limit);
        IPage<SaleContractSubsidyPriceVO> iPage = mapper.queryPage(voPage, searchVal, orgId, status, startDate, endDate, pumpNormId, sales);
        /**分页插件**/
        if (!StringUtils.isNull(iPage.getRecords())) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal())) iPage.setTotal(pageInfo.getTotal());
            List<SaleContractSubsidyPriceVO> records = iPage.getRecords();
            if (CollUtil.isNotEmpty(records)) {
                List<Long> indenIdList = records.stream().map(SaleContractSubsidyPriceVO::getIndentId).collect(Collectors.toList());
                Map<String, String> indenIdMap = queryProductionIndent(records.get(0).getOrgId(), indenIdList);
                records.forEach(item -> {
                    item.setIndentSite(indenIdMap.get(item.getIndentId().toString()));
                });
                iPage.setRecords(records);
            }
        }
        return iPage;
    }

    /**
     * 新增数据
     *
     * @param dto page
     * @return
     */
    public RestResultDto saveInit(SaleContractSubsidyPrice dto) {
        List<ContractDayPrice> list = querySaleContractSubsidyPrice(dto.getContractId(), dto.getOrgId(), dto.getIndentId(), dto.getToday(), dto.getSubsidyType(), dto.getCountType());
        if (CollUtil.isNotEmpty(list)) {
            return RestResultDto.fail("当前合同补贴日期已经存在!");
        }
        SaleContract contract = saleContractDao.selectById(dto.getContractId());
        DataSourceInfo ds = dataSourceInfoDao.queryDSByOriginId(contract.getOrgId());
        SaleClient client = saleClientDao.selectById(contract.getClientId());
        String subsidyType = "";
        String countType = "";
        Date nowDate = new Date();
        for (int i = 0; i < ContractSubsidyTypeEnum.values().length; i++) {
            if (ContractSubsidyTypeEnum.values()[i].getCode().intValue() == dto.getSubsidyType().intValue()) {
                subsidyType = ContractSubsidyTypeEnum.values()[i].getDescription();
                break;
            }
        }
        for (int i = 0; i < SubsidyCountTypeEnum.values().length; i++) {
            if (SubsidyCountTypeEnum.values()[i].getCode().intValue() == dto.getCountType().intValue()) {
                countType = SubsidyCountTypeEnum.values()[i].getDescription();
                break;
            }
        }

        ContractDayPrice dayPrice = new ContractDayPrice(contract.getOrgId(), ds.getName(), ds.getId(), ds.getCode(), dto.getToday(), "08:30:00", BillTimeTypeEnum.SYSTEM.getCode(), contract.getId(), contract.getErpid(), contract.getCode(), contract.getName(), client.getFullName(), contract.getBuild(), contract.getSales(), dto.getIndentId(), dto.getErpIndentId(), dto.getIndentSite(), IsAutoEnum.SD.getCode(), DayPriceTypeEnum.SUBSIDY.getCode(), dto.getSubsidyType().longValue(), subsidyType, dto.getCountType().longValue(), countType, dto.getCount(), dto.getPrice(), dto.getSumPrice(), dto.getPumpNormId(), dto.getPumpNormName(), 0.0, 0.0, CheckEnum.UHE.getCode(), null, null, "", null, CheckEnum.UHE.getCode(), null, null, "", null, 0, nowDate, dto.getCreator(), -1);
        ContractDayPrice dayPrice1 = new ContractDayPrice(contract.getOrgId(), ds.getName(), ds.getId(), ds.getCode(), dto.getToday(), contract.getBillTime(), BillTimeTypeEnum.CUSTOM.getCode(), contract.getId(), contract.getErpid(), contract.getCode(), contract.getName(), client.getFullName(), contract.getBuild(), contract.getSales(), dto.getIndentId(), dto.getErpIndentId(), dto.getIndentSite(), IsAutoEnum.SD.getCode(), DayPriceTypeEnum.SUBSIDY.getCode(), dto.getSubsidyType().longValue(), subsidyType, dto.getCountType().longValue(), countType, dto.getCount(), dto.getPrice(), dto.getSumPrice(), dto.getPumpNormId(), dto.getPumpNormName(), 0.0, 0.0, CheckEnum.UHE.getCode(), null, null, "", null, CheckEnum.UHE.getCode(), null, null, "", null, 0, nowDate, dto.getCreator(), -1);
        if(StrUtil.isNotEmpty(dto.getRemark())){
            dayPrice.setRemarks(dto.getRemark());
            dayPrice1.setRemarks(dto.getRemark());
        }
        contractDayPriceDao.insert(dayPrice);
        contractDayPriceDao.insert(dayPrice1);
        return RestResultDto.success("保存成功!");
    }

    /**
     * 更新数据
     *
     * @return
     */
    public RestResultDto updateStausById(Long id, SysUser user) {

        ContractDayPrice contractDayPrice = contractDayPriceDao.selectById(id);
        if (ObjectUtil.isEmpty(contractDayPrice)) {
            return RestResultDto.fail("当前数据不存在!");
        }
        if (contractDayPrice.getStatus().intValue() == 1) {
            return RestResultDto.fail("当前数据已作废!");
        }
        Integer billTimeType = 0;
        contractDayPrice.setStatus(1);
        contractDayPrice.setUpdater(user.getName());
        contractDayPrice.setUpdateTime(new Date());
        if (contractDayPrice.getBillTimeType().intValue() == 0) {
            billTimeType = BillTimeTypeEnum.CUSTOM.getCode();
        }

        QueryWrapper<ContractDayPrice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("org_id", contractDayPrice.getOrgId());
        queryWrapper.eq("con_id", contractDayPrice.getConId());
        queryWrapper.eq("day", contractDayPrice.getDay());
        queryWrapper.eq("indent_id", contractDayPrice.getIndentId());
        queryWrapper.eq("price_type", DayPriceTypeEnum.SUBSIDY.getCode());
        queryWrapper.eq("total_level_price", contractDayPrice.getTotalLevelPrice());
        queryWrapper.lambda().eq(ContractDayPrice::getBillTimeType, billTimeType);
        List<ContractDayPrice> listDayPrice = contractDayPriceDao.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(listDayPrice)) {
            ContractDayPrice dbprice = listDayPrice.get(0);
            dbprice.setStatus(1);
            dbprice.setUpdater(user.getName());
            dbprice.setUpdateTime(new Date());
            contractDayPriceDao.updateById(dbprice);
        }
        int saveStatus = contractDayPriceDao.updateById(contractDayPrice);
        if (saveStatus > 0) {
            return RestResultDto.success("更新成功!");
        } else {
            return RestResultDto.success("更新失败!");
        }
    }


    public RestResultDto update(SaleContractSubsidyPrice dto) {
        ContractDayPrice db = contractDayPriceDao.selectById(dto.getId());
        if (ObjectUtil.isEmpty(db)) {
            return RestResultDto.fail("当前数据不存在!");
        }
        List<ContractDayPrice> list = querySaleContractSubsidyPrice(dto.getContractId(), dto.getOrgId(), dto.getIndentId(), dto.getToday(), dto.getSubsidyType(), dto.getCountType());
        if (CollUtil.isNotEmpty(list)) {
            for (ContractDayPrice price : list) {
                if ((!price.getId().equals(dto.getId())) && (price.getBillTimeType().intValue() == db.getBillTimeType().intValue())) {
                    return RestResultDto.fail("当前合同补贴日期已经存在!");
                }
            }
        }
        SaleContract contract = saleContractDao.selectById(dto.getContractId());
        DataSourceInfo ds = dataSourceInfoDao.queryDSByOriginId(contract.getOrgId());
        SaleClient client = saleClientDao.selectById(contract.getClientId());
        String subsidyType = "";
        String countType = "";
        Date nowDate = new Date();
        for (int i = 0; i < ContractSubsidyTypeEnum.values().length; i++) {
            if (ContractSubsidyTypeEnum.values()[i].getCode().intValue() == dto.getSubsidyType().intValue()) {
                subsidyType = ContractSubsidyTypeEnum.values()[i].getDescription();
                break;
            }
        }
        for (int i = 0; i < SubsidyCountTypeEnum.values().length; i++) {
            if (SubsidyCountTypeEnum.values()[i].getCode().intValue() == dto.getCountType().intValue()) {
                countType = SubsidyCountTypeEnum.values()[i].getDescription();
                break;
            }
        }

        Integer billTimeType = 0;
        String billTime = "08:30:00";
        if (db.getBillTimeType().intValue() == 0) {
            billTimeType = BillTimeTypeEnum.CUSTOM.getCode();
            billTime = "08:30:00";
        }else{
            billTime = contract.getBillTime();
        }
        ContractDayPrice dayPrice = new ContractDayPrice(contract.getOrgId(), ds.getName(), ds.getId(), ds.getCode(), dto.getToday(), billTime, db.getBillTimeType(), contract.getId(), contract.getErpid(), contract.getCode(), contract.getName(), client.getFullName(), contract.getBuild(), contract.getSales(), dto.getIndentId(), dto.getErpIndentId(), dto.getIndentSite(), IsAutoEnum.SD.getCode(), DayPriceTypeEnum.SUBSIDY.getCode(), dto.getSubsidyType().longValue(), subsidyType, dto.getCountType().longValue(), countType, dto.getCount(), dto.getPrice(), dto.getSumPrice(), dto.getPumpNormId(), dto.getPumpNormName(), 0.0, 0.0, CheckEnum.UHE.getCode(), null, null, "", null, CheckEnum.UHE.getCode(), null, null, "", null, 0, nowDate, dto.getCreator(), -1);
        dayPrice.setId(db.getId());
        dayPrice.setCreater(db.getCreater());
        dayPrice.setCreateTime(db.getCreateTime());
        dayPrice.setUpdater(dto.getUpdator());
        dayPrice.setUpdateTime(new Date());
        if(StrUtil.isNotEmpty(dto.getRemark())){
            dayPrice.setRemarks(dto.getRemark());
        }
        contractDayPriceDao.updateById(dayPrice);

        QueryWrapper<ContractDayPrice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("org_id", db.getOrgId());
        queryWrapper.eq("con_id", db.getConId());
        queryWrapper.eq("day", db.getDay());
        queryWrapper.eq("indent_id", db.getIndentId());
        queryWrapper.eq("price_type", DayPriceTypeEnum.SUBSIDY.getCode());
        queryWrapper.eq("total_level_price", db.getTotalLevelPrice());
        queryWrapper.lambda().eq(ContractDayPrice::getBillTimeType, billTimeType);
        List<ContractDayPrice> listDayPrice = contractDayPriceDao.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(listDayPrice)) {
            ContractDayPrice dbprice = listDayPrice.get(0);
            if (dbprice.getBillTimeType().intValue() == 0) {
                billTime = "08:30:00";
            }else{
                billTime = contract.getBillTime();
            }
            ContractDayPrice dayPriceType = new ContractDayPrice(contract.getOrgId(), ds.getName(), ds.getId(), ds.getCode(), dto.getToday(), billTime, dbprice.getBillTimeType(), contract.getId(), contract.getErpid(), contract.getCode(), contract.getName(), client.getFullName(), contract.getBuild(), contract.getSales(), dto.getIndentId(), dto.getErpIndentId(), dto.getIndentSite(), IsAutoEnum.SD.getCode(), DayPriceTypeEnum.SUBSIDY.getCode(), dto.getSubsidyType().longValue(), subsidyType, dto.getCountType().longValue(), countType, dto.getCount(), dto.getPrice(), dto.getSumPrice(), dto.getPumpNormId(), dto.getPumpNormName(), 0.0, 0.0, CheckEnum.UHE.getCode(), null, null, "", null, CheckEnum.UHE.getCode(), null, null, "", null, 0, nowDate, dto.getCreator(), -1);
            dayPriceType.setId(dbprice.getId());
            dayPriceType.setCreateTime(dbprice.getCreateTime());
            dayPriceType.setCreater(dbprice.getCreater());
            dayPriceType.setUpdater(dto.getUpdator());
            dayPriceType.setUpdateTime(new Date());
            if(StrUtil.isNotEmpty(dto.getRemark())){
                dayPriceType.setRemarks(dto.getRemark());
            }
            contractDayPriceDao.updateById(dayPriceType);
        }
        return RestResultDto.success("更新成功!");

    }

    /**
     * 根据公司标识和合同标识查询浇筑部位
     *
     * @param orgId 公司ID
     * @param conId 合同ID
     * @return
     */
    public List<Map<String, Object>> queryByOrgIdAndConId(Long orgId, Long conId,String startDate,String endDate) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        DataSourceInfo ds = dataSourceInfoDao.queryDSByOriginId(orgId);
        if (ObjectUtil.isEmpty(ds)) {
            return null;
        }
		List<Map<String, Object>> list = mapper.queryByOrgIdAndConId(ds.getCode(), orgId, conId, startDate, endDate);
		;
        if (CollUtil.isNotEmpty(list)) {
            resultList.addAll(list);
        }
        return resultList;
    }


    public List<ContractDayPrice> querySaleContractSubsidyPrice(Long conId, Long orgId, Long indentId, String today, Integer subsidyType, Integer countType) {
        QueryWrapper<ContractDayPrice> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ContractDayPrice::getConId, conId);
        queryWrapper.lambda().eq(ContractDayPrice::getOrgId, orgId);
        queryWrapper.lambda().eq(ContractDayPrice::getIndentId, indentId);
        queryWrapper.lambda().eq(ContractDayPrice::getDay, today);
        queryWrapper.lambda().eq(ContractDayPrice::getStrengthId, subsidyType);
        queryWrapper.lambda().eq(ContractDayPrice::getTechId, countType);
        queryWrapper.lambda().eq(ContractDayPrice::getStatus, 0);
        return contractDayPriceDao.selectList(queryWrapper);
    }

    public Map<String, String> queryProductionIndent(Long orgId, List<Long> indenIdList) {
        Map<String, String> resultMap = new HashMap<>(16);
        DataSourceInfo ds = dataSourceInfoDao.queryDSByOriginId(orgId);
        if (ObjectUtil.isEmpty(ds)) {
            return null;
        }
        //	查询oa中的任务单
		List<Map<String, Object>> list = mapper.queryIndenByIds(ds.getCode(), indenIdList);
		;
		if (CollUtil.isNotEmpty(list)) {
            resultMap = list.stream().collect(Collectors.toMap(map -> map.get("id").toString(), map -> map.get("name").toString()));
        }
        return resultMap;
    }


    @Override
    public boolean saveBatch(Collection<SaleContractSubsidyPrice> entityList) {
        int count = mapper.saveBatch(entityList);
        return false;
    }

    @Override
    public int updateByBill(Long id, Integer isBill, String name) {
        ContractDayPrice contractDayPrice = contractDayPriceDao.selectById(id);
        if(ObjectUtil.isEmpty(contractDayPrice)){
            throw new SnakerException("当前数据不存在！");
        }
        contractDayPrice.setIsBill(isBill);
        contractDayPrice.setUpdateTime(new Date());
        contractDayPrice.setUpdater(name);

        Integer billTimeType = 0;
        if (contractDayPrice.getBillTimeType().intValue() == 0) {
            billTimeType = BillTimeTypeEnum.CUSTOM.getCode();
        }
        QueryWrapper<ContractDayPrice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("org_id", contractDayPrice.getOrgId());
        queryWrapper.eq("con_id", contractDayPrice.getConId());
        queryWrapper.eq("day", contractDayPrice.getDay());
        queryWrapper.eq("indent_id", contractDayPrice.getIndentId());
        queryWrapper.eq("price_type", DayPriceTypeEnum.SUBSIDY.getCode());
        queryWrapper.eq("total_level_price", contractDayPrice.getTotalLevelPrice());
        queryWrapper.lambda().eq(ContractDayPrice::getBillTimeType, billTimeType);
        List<ContractDayPrice> listDayPrice = contractDayPriceDao.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(listDayPrice)) {
            ContractDayPrice dbprice = listDayPrice.get(0);
            dbprice.setIsBill(isBill);
            dbprice.setUpdater(name);
            dbprice.setUpdateTime(new Date());
            contractDayPriceDao.updateById(dbprice);
        }
        int saveStatus = contractDayPriceDao.updateById(contractDayPrice);
        return saveStatus;
    }
}